msg_tool\scripts\escude\ops/
panicon.rs

1use super::super::script::ReadParam;
2use super::base::CustomOps;
3use crate::ext::io::*;
4use anyhow::Result;
5use int_enum::IntEnum;
6use std::collections::HashMap;
7use std::io::Seek;
8
9#[repr(u8)]
10#[derive(Debug, IntEnum)]
11enum PaniconOp {
12    End = 0x22,
13    Jump,
14    Call,
15    AutoPlay,
16    Frame,
17    Text,
18    Clear,
19    Gap,
20    Mes,
21    Tlk,
22    Menu,
23    Select,
24    LsfInit,
25    LsfSet,
26    Cg,
27    Em,
28    Clr,
29    Disp,
30    Path,
31    Trans,
32    BgmPlay,
33    BgmStop,
34    BgmVolume,
35    BgmFx,
36    AmbPlay,
37    AmbStop,
38    AmbVolume,
39    AmbFx,
40    SePlay,
41    SeStop,
42    SeWait,
43    SeVolume,
44    SeFx,
45    VocPlay,
46    VocStop,
47    VocWait,
48    VocVolume,
49    VocFx,
50    Quake,
51    Flash,
52    Filter,
53    Effect,
54    Sync,
55    Wait,
56    Movie,
57    Credit,
58    Event,
59    Scene,
60    Title,
61    Notice,
62    SetPass,
63    IsPass,
64    AutoSave,
65    Place,
66    OpenName,
67    Name,
68    LogNew,
69    LogOut,
70}
71
72#[derive(Debug)]
73pub struct PaniconOps<T: std::fmt::Debug + std::hash::Hash> {
74    prev_name: Option<T>,
75    menus: HashMap<T, T>,
76    last_select: usize,
77}
78
79impl<T: std::fmt::Debug + std::hash::Hash> PaniconOps<T> {
80    pub fn new() -> Self {
81        Self {
82            prev_name: None,
83            menus: HashMap::new(),
84            last_select: 0,
85        }
86    }
87}
88
89use PaniconOp::*;
90
91impl<T> CustomOps<T> for PaniconOps<T>
92where
93    T: std::fmt::Debug + TryInto<u64> + std::hash::Hash,
94{
95    fn run<'a>(&mut self, vm: &mut super::super::script::VM<'a, T>, op: u8) -> Result<bool>
96    where
97        MemReaderRef<'a>: ReadParam<T>,
98        T: TryInto<u64>
99            + Default
100            + Eq
101            + Ord
102            + Copy
103            + std::fmt::Debug
104            + std::fmt::Display
105            + std::hash::Hash
106            + From<u8>
107            + std::ops::Neg<Output = T>
108            + std::ops::Add<Output = T>
109            + std::ops::Sub<Output = T>
110            + std::ops::Mul<Output = T>
111            + std::ops::Div<Output = T>
112            + std::ops::Rem<Output = T>
113            + std::ops::Not<Output = T>
114            + std::ops::BitAnd<Output = T>
115            + std::ops::BitOr<Output = T>
116            + std::ops::BitXor<Output = T>
117            + std::ops::Shr<Output = T>
118            + std::ops::Shl<Output = T>,
119        anyhow::Error: From<<T as TryInto<u64>>::Error>,
120    {
121        if let Ok(op) = PaniconOp::try_from(op) {
122            // println!("Running Panicon operation: {:?}", op);
123            match op {
124                End => vm.skip_n_params(1, false),
125                Jump => vm.skip_n_params(1, false),
126                Call => vm.skip_n_params(1, false),
127                AutoPlay => vm.skip_n_params(1, false),
128                Frame => vm.skip_n_params(1, false),
129                Text => vm.skip_n_params(2, false),
130                Clear => vm.skip_n_params(1, false),
131                Gap => vm.skip_n_params(2, false),
132                // Handle concat name
133                Mes => {
134                    let mes = vm.pop_data()?;
135                    vm.mess.insert(mes);
136                    if let Some(name) = self.prev_name.take() {
137                        vm.names.insert(mes, name);
138                    }
139                    Ok(false)
140                }
141                Tlk => {
142                    let params = vm.read_params(None)?;
143                    let name = params
144                        .get(0)
145                        .cloned()
146                        .ok_or(anyhow::anyhow!("Missing name parameter"))?;
147                    self.prev_name = Some(name);
148                    Ok(false)
149                }
150                Menu => {
151                    let params = vm.read_params(Some(3))?;
152                    let id = params[0];
153                    let mes = params[1];
154                    vm.mess.insert(mes);
155                    self.menus.insert(id, mes);
156                    Ok(false)
157                }
158                Select => {
159                    if let Some(var) = vm.vars.get_mut(&T::from(131)) {
160                        *var = *var + T::from(1);
161                        return Ok(false);
162                    }
163                    let offset = vm.reader.stream_position()? - 1;
164                    for _ in self.last_select + 1..self.menus.len() {
165                        vm.stack.push(offset);
166                        // println!("Pushing offset: {offset:#x} to stack");
167                    }
168                    vm.vars.insert(T::from(131), T::from(0));
169                    vm.skip_n_params(2, false)
170                }
171                LsfInit => vm.skip_n_params(1, false),
172                LsfSet => vm.skip_params(false),
173                Cg => vm.skip_params(false),
174                Em => vm.skip_n_params(5, false),
175                Clr => vm.skip_n_params(1, false),
176                Disp => vm.skip_n_params(4, false),
177                Path => vm.skip_params(false),
178                Trans => Ok(false),
179                BgmPlay => vm.skip_n_params(3, false),
180                BgmStop => vm.skip_n_params(1, false),
181                BgmVolume => vm.skip_n_params(2, false),
182                BgmFx => vm.skip_n_params(1, false),
183                AmbPlay => vm.skip_n_params(3, false),
184                AmbStop => vm.skip_n_params(1, false),
185                AmbVolume => vm.skip_n_params(2, false),
186                AmbFx => vm.skip_n_params(1, false),
187                SePlay => vm.skip_n_params(5, false),
188                SeStop => vm.skip_n_params(2, false),
189                SeWait => vm.skip_n_params(1, false),
190                SeVolume => vm.skip_n_params(3, false),
191                SeFx => vm.skip_n_params(1, false),
192                VocPlay => vm.skip_n_params(4, false),
193                VocStop => vm.skip_n_params(2, false),
194                VocWait => vm.skip_n_params(1, false),
195                VocVolume => vm.skip_n_params(3, false),
196                VocFx => vm.skip_n_params(1, false),
197                Quake => vm.skip_n_params(4, false),
198                Flash => vm.skip_n_params(2, false),
199                Filter => vm.skip_n_params(2, false),
200                Effect => vm.skip_n_params(1, false),
201                Sync => vm.skip_n_params(2, false),
202                Wait => vm.skip_n_params(1, false),
203                Movie => vm.skip_n_params(1, false),
204                Credit => vm.skip_n_params(1, false),
205                Event => vm.skip_n_params(1, false),
206                Scene => vm.skip_n_params(1, false),
207                Title => {
208                    let title = vm.pop_data()?;
209                    vm.mess.insert(title);
210                    Ok(false)
211                }
212                Notice => {
213                    let notice = vm.pop_data()?;
214                    vm.mess.insert(notice);
215                    vm.skip_n_params(2, false)
216                }
217                SetPass => vm.skip_n_params(2, false),
218                IsPass => vm.skip_n_params(1, false),
219                AutoSave => Ok(false),
220                Place => vm.skip_n_params(1, false),
221                OpenName => vm.skip_n_params(1, false),
222                Name => {
223                    eprintln!("Name operation.");
224                    let mes = vm.pop_data()?;
225                    let name = vm.pop_data()?;
226                    vm.mess.insert(mes);
227                    vm.names.insert(mes, name);
228                    Ok(false)
229                }
230                LogNew => vm.skip_n_params(1, false),
231                LogOut => vm.skip_params(false),
232            }
233        } else {
234            // return Err(anyhow::anyhow!("Unknown Panicon operation: {op:#02x}"));
235            Ok(false)
236        }
237    }
238}